angular.module('app').component('winitFeatureMap', {
    templateUrl: getTemplateUrl('matrix/component/tpl/winitFeatureMap.html'),
    bindings: {
        isFeatureMap: '<',
        relateList: '<',
        mapDatas: '<',
        blur: '&',
        search: "=",
        moveFun: '&',
        addMenuFun: '&',
        addPageFun: '&',
        addFeatureFun: '&',
        removeFun: '&',
        editFun: '&',
        findFeatureFun: '&',
        historyFun: '&',
        sortFun: '&',
        relateFun: '&',
        reliveFun: '&',
        diagramScope: "=",
        selectSysFun:"&"
    },
    controller: function ($scope, $rootScope, $element, $attrs, $timeout, lodash) {
        var ctrl = this;
        //监听模型数据的变化
        var $ = go.GraphObject.make;

        $scope.sysList = config_flow_legend_sys;
        $scope.selectSys = {"crtname": "请选择系统"};
        $scope.sltSys = "";

        $scope.selectSysItem = function (item) {
            $scope.sltSys = item;
            ctrl.selectSysFun({item:item});
        }
        //  禁止右键
        if (window.Event)
            document.captureEvents(Event.MOUSEUP);

        function nocontextmenu(event) {
            event.cancelBubble = true
            event.returnValue = false;

            return false;
        }

        function norightclick(e) {
            if (window.Event) {
                if (e.which == 2 || e.which == 3)
                    return false;
            } else if (event.button == 2 || event.button == 3) {
                event.cancelBubble = true
                event.returnValue = false;
                return false;
            }
        }

        document.oncontextmenu = nocontextmenu;
        document.onmousedown = norightclick;
        // end 禁止右键

        //自适应高度
        ctrl.setTableHeight = function () {
            $timeout(function () {
                var h = document.documentElement.clientHeight || document.body.clientHeight;
                h = h - 250;
                if (document.getElementById("myDiagramDiv")) {
                    document.getElementById("myDiagramDiv").style.height = h + "px";
                }
            })
        }
        ctrl.setTableHeight();
        window.onresize = ctrl.setTableHeight;

        //添加节点右键点击菜单 start
        var cxElement = document.getElementById("contextMenu");
        var myContextMenu = $(go.HTMLInfo, {
            show: showContextMenu,
            mainElement: cxElement
        })

        function showContextMenu(obj, diagram, tool) {
            diagram.selection.each(function (node) {
                $scope.selectNode = node;
            })
            ctrl.blur({info: $scope.selectNode.data});

            //有多少个按钮就添加多少个按钮  控制该不该显示
            document.getElementById("move").style.display = canBtnShow("move") ? "block" : "none";
            document.getElementById("addMenu").style.display = canBtnShow("addMenu") ? "block" : "none";
            document.getElementById("addPage").style.display = canBtnShow("addPage") ? "block" : "none";
            document.getElementById("addFeature").style.display = canBtnShow("addFeature") ? "block" : "none";
            document.getElementById("removeNode").style.display = canBtnShow("remove") ? "block" : "none";
            document.getElementById("edit").style.display = canBtnShow("edit") ? "block" : "none";
            document.getElementById("findFeature").style.display = canBtnShow("findFeature") ? "block" : "none";
            document.getElementById("history").style.display = canBtnShow("history") ? "block" : "none";
            document.getElementById("toSort").style.display = canBtnShow("toSort") ? "block" : "none";
            document.getElementById("relate").style.display = canBtnShow("relate") ? "block" : "none";
            document.getElementById("relive").style.display = canBtnShow("relive") ? "block" : "none";

            cxElement.style.display = "block";
            var mousePt = diagram.lastInput.viewPoint;
            cxElement.style.left = mousePt.x + "px";
            cxElement.style.top = mousePt.y + "px";
        }

        function canBtnShow(type) {
            var data = $scope.selectNode.data;
            switch (type) {
                case "move":
                    return ((data.mapType == 'MENU' || data.mapType == 'PAGE' || data.mapType == 'FEATURE' || data.mapType == 'PROTOTYPE') && data.parentId != '-1' && data.level != '1' && data.type != 'PROTOTYPE') ? true : false;
                    break;
                case "addMenu":
                    return (data.mapType == 'MENU' || data.mapType == 'SYS') ? true : false;
                    break;
                case "addPage":
                    return data.mapType == 'MENU' ? true : false;
                    break;
                case "addFeature":
                    return data.mapType == 'PAGE' ? true : false;
                    break;
                case "remove":
                    return (data.mapType != undefined && data.mapType != 'SYS' && data.type != 'PROTOTYPE') ? true : false;
                    break;
                case "edit":
                    return (data.mapType != undefined && data.mapType != 'SYS' && data.type != 'PROTOTYPE') ? true : false;
                    break;
                case "findFeature":
                    return (data.mapType == 'FEATURE' || data.mapType == 'PROTOTYPE') ? true : false;
                    break;
                case "history":
                    return (data.mapType == 'FEATURE' || data.mapType == 'PROTOTYPE') ? true : false;
                    break;
                case "toSort":
                    return data.parent != "0" ? true : false;
                    break;
                case "relate":
                    return (data.mapType == 'FEATURE' || data.mapType == 'PROTOTYPE') && data.isRelate == undefined ? true : false;
                    break;
                case "relive":
                    return (data.mapType == 'FEATURE' || data.mapType == 'PROTOTYPE') && data.isRelate != undefined ? true : false;
                    break;
            }
        }

        // 移动
        $scope.moveBtn = function () {
            ctrl.moveFun();
            ctrl.myDiagram.currentTool.stopTool();
        }
        // 添加菜单
        $scope.addMenuBtn = function () {
            ctrl.addMenuFun();
            ctrl.myDiagram.currentTool.stopTool();
        }
        // 添加页面
        $scope.addPageBtn = function () {
            ctrl.addPageFun();
            ctrl.myDiagram.currentTool.stopTool();
        }
        // 添加功能点
        $scope.addFeatureBtn = function () {
            ctrl.addFeatureFun();
            ctrl.myDiagram.currentTool.stopTool();
        }
        // 删除
        $scope.removeBtn = function () {
            ctrl.removeFun();
            ctrl.myDiagram.currentTool.stopTool();
        }
        // 修改标题
        $scope.editBtn = function () {
            ctrl.editFun();
            ctrl.myDiagram.currentTool.stopTool();
        };
        // 查看功能点
        $scope.findFeatureBtn = function () {
            ctrl.findFeatureFun();
            ctrl.myDiagram.currentTool.stopTool();
        }
        // 历史记录
        $scope.historyBtn = function () {
            ctrl.historyFun();
            ctrl.myDiagram.currentTool.stopTool();
        }
        // 排序
        $scope.sortBtn = function () {
            ctrl.sortFun();
            ctrl.myDiagram.currentTool.stopTool();
        }
        // 拉分支
        $scope.relateBtn = function() {
            ctrl.relateFun();
            ctrl.myDiagram.currentTool.stopTool();
        }
        // 重置
        $scope.reliveBtn = function() {
            ctrl.reliveFun();
            ctrl.myDiagram.currentTool.stopTool();
        }

        //添加节点右键点击菜单 end

        ctrl.myDiagram =
            $(go.Diagram, "myDiagramDiv", //页面中div的id
                {
                    "toolManager.hoverDelay": 100, // 100 milliseconds instead of the default 850
                    // "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,
                    isReadOnly: true,
                    grid: $(go.Panel, "Grid", {gridCellSize: new go.Size(8, 8)},
                        $(go.Shape, "LineH", {stroke: "lightgray", strokeWidth: 0.5}),
                        $(go.Shape, "LineV", {stroke: "lightgray", strokeWidth: 0.5})
                    ),
                    allowCopy: false,
                    // initialContentAlignment: go.Spot.MiddleTop, // center the content
                    layout: // create a TreeLayout for the family tree
                        $(go.TreeLayout, {
                            angle: 90,
                            nodeSpacing: 5,
                            layerSpacing: 20,
                            layerStyle: go.TreeLayout.LayerUniform
                        }),
                });

        // 禁止动画效果
        ctrl.myDiagram.animationManager.isEnabled = false;
        
        //图形颜色
        var head = '#d4e2ef';
        var menu = '#e6f0d8';
        var page = '#fbe6d1';
        var feature = '#e2d8e8';
        var desc = '#21d6ef';
        //回执图例描述
        ctrl.myDiagram.add(
            $(go.Part, "Table", {position: new go.Point(-100, 70), selectable: false},
                $(go.TextBlock, "", {row: 0, font: "700 14px Droid Serif, sans-serif"}), // end row 0
                $(go.Panel, "Horizontal", {row: 1, alignment: go.Spot.Left},
                    $(go.Shape, "Rectangle", {desiredSize: new go.Size(30, 30), fill: head, margin: 5}),
                    $(go.TextBlock, "系统", {font: "700 13px Droid Serif, sans-serif"})
                ), // end row 1
                $(go.Panel, "Horizontal", {row: 2, alignment: go.Spot.Left},
                    $(go.Shape, "Rectangle", {desiredSize: new go.Size(30, 30), fill: menu, margin: 5}),
                    $(go.TextBlock, "菜单", {font: "700 13px Droid Serif, sans-serif"})
                ), // end row 2
                $(go.Panel, "Horizontal", {row: 3, alignment: go.Spot.Left},
                    $(go.Shape, "Rectangle", {desiredSize: new go.Size(30, 30), fill: page, margin: 5}),
                    $(go.TextBlock, "页面", {font: "700 13px Droid Serif, sans-serif"})
                ),
                $(go.Panel, "Horizontal", {row: 4, alignment: go.Spot.Left},
                    $(go.Shape, "Rectangle", {desiredSize: new go.Size(30, 30), fill: feature, margin: 5}),
                    $(go.TextBlock, "功能点", {font: "700 13px Droid Serif, sans-serif"})
                ), // end row 4
                $(go.Panel, "Horizontal", {row: 5, alignment: go.Spot.Left},
                    $(go.Shape, "Rectangle", {desiredSize: new go.Size(30, 30), fill: desc, margin: 5}),
                    $(go.TextBlock, "页面", {font: "700 13px Droid Serif, sans-serif"})
                ) // end row 4
            ));

        // 获取数据转化数据格式
        function tooltipTextConverter(person) {
            var str = "";
            str += "名称: " + person.name;
            if (person.path !== undefined) str += "\nPath " + person.path;
            if (person.reign !== undefined) str += "\nReign: " + person.reign;
            return str;
        }

        //节点提示文字
        var tooltiptemplate =
            $(go.Adornment, "Auto",
                $(go.Shape, "Rectangle", {fill: "whitesmoke", stroke: "black"}),
                $(go.TextBlock, {
                        font: "bold 8pt Helvetica, bold Arial, sans-serif",
                        wrap: go.TextBlock.WrapFit,
                        margin: 5
                    },
                    new go.Binding("text", "", tooltipTextConverter))
            );

        // define Converters to be used for Bindings
        function brushConverter(mapType) {
            if (mapType === "SYS") return head;
            if (mapType === "MENU") return menu;
            if (mapType === "PAGE") return page;
            if (mapType === "FEATURE") return feature;
            if (mapType === "PROTOTYPE") return desc;
            return "orange";
        }

        //设置节点模板
        ctrl.myDiagram.nodeTemplate =
            $(go.Node, "Vertical", {
                    deletable: false,
                    toolTip: tooltiptemplate,
                    isTreeExpanded: false,
                    contextMenu: myContextMenu
                },
                new go.Binding("text", "name"),
                $(go.Panel, "Auto",
                    $(go.Shape, "Rectangle", {
                            fill: "lightgray",
                            stroke: null,
                            strokeWidth: 2,
                            stretch: go.GraphObject.Fill,
                            alignment: go.Spot.Center
                        },
                        new go.Binding("stroke", "isRelate").makeTwoWay(),
                        new go.Binding("fill", "mapType", brushConverter)),
                    $(go.TextBlock, {
                            font: "700 12px Droid Serif, sans-serif",
                            textAlign: "center",
                            margin: 10,
                            maxSize: new go.Size(80, NaN)
                        },
                        new go.Binding("stroke", "isHighlighted",
                            function (h) {
                                return h ? "red" : "black";
                            }).ofObject(),
                        new go.Binding("text", "name")
                    )
                ),
                $(go.Panel, // this is underneath the "BODY"
                    {height: 15}, // always this height, even if the TreeExpanderButton is not visible
                    $("TreeExpanderButton")
                )
            );

        //连接线模板
        ctrl.myDiagram.linkTemplate =
            $(go.Link, // the whole link panel
                {routing: go.Link.Orthogonal, corner: 5, selectable: false},
                $(go.Shape, {strokeWidth: 3, stroke: '#424242'})); // the gray link shape

        // 监听数据变化更新数据
        ctrl.$onChanges = function () {
            ctrl.myDiagram.model = new go.TreeModel(ctrl.mapDatas);
        }

        //缩小事件
        $scope.zoomToFit = function () {
            ctrl.myDiagram.zoomToFit();
        };

        //居中事件
        $scope.centerRoot = function () {
            ctrl.myDiagram.scale = 1;
        };

        //添加节点，父节点没有展开时展开并添加
        $scope.createNode = function (childdata) {
            var diagram = $scope.selectNode.diagram;
            diagram.startTransaction("CollapseExpandTree");
            var data = $scope.selectNode.data;
            if (!data.everExpanded) {
                //展开父节点
                diagram.model.setDataProperty(data, "everExpanded", true);
            }
            createSubTree(data, childdata);
            diagram.commandHandler.expandTree($scope.selectNode);
            diagram.commitTransaction("CollapseExpandTree");
            // ctrl.myDiagram.zoomToFit();
        }

        function createSubTree(parentdata, childdata) {
            var model = ctrl.myDiagram.model;
            var parent = ctrl.myDiagram.findNodeForData(parentdata);

            childdata.parent = childdata.parent ? childdata.parent : parentdata.key;
            model.addNodeData(childdata);
            var child = ctrl.myDiagram.findNodeForData(childdata);
            child.location = parent.location;
        }

        $scope.updateNode = function (relateType, value) {
            if(relateType) {
                if($scope.selectNode.data.mapType == "FEATURE") {
                    $scope.selectNode.data.isRelate = value ? "red" : null;
                }
                if(value) {
                    // $scope.selectNode.data.id = value.id;
                    // $scope.selectNode.data.sys = value.sys;
                    // $scope.selectNode.data.featureName = value.name;
                    // $scope.selectNode.data.status = "ADD";
                    // ctrl.relateList.push($scope.selectNode.data);
                } else {
                    $scope.selectNode.data.isRelate = null;
                    lodash.remove(ctrl.relateList, function(data) {
                        return data.id = $scope.selectNode.data.id;
                    })
                }
            }
            $scope.selectNode.updateTargetBindings();
        };
        $scope.moveNode = function (data) {
            var oldP = $scope.selectNode.findTreeParentNode();
            if (!oldP.data.everExpanded) {
                // 关闭旧父节点
                ctrl.myDiagram.model.setDataProperty(oldP.data, "everExpanded", false);
            }
            ctrl.myDiagram.commandHandler.collapseTree(oldP);

            var newP = ctrl.myDiagram.findNodeForKey(data.parent);
            if (!newP.data.everExpanded) {
                //展开新父节点
                ctrl.myDiagram.model.setDataProperty(newP.data, "everExpanded", true);
            }
            ctrl.myDiagram.commandHandler.expandTree(newP);

            ctrl.myDiagram.model.removeNodeData($scope.selectNode.data);
            ctrl.myDiagram.model.addNodeData(data);

            addChild($scope.selectNode)

            // ctrl.myDiagram.zoomToFit();
        };

        function addChild(node) {
            node.findTreeChildrenNodes().each(function (child) {
                ctrl.myDiagram.model.removeNodeData(child.data);
                ctrl.myDiagram.model.addNodeData(child.data);
                if (node.findTreeChildrenNodes().count > 0) {
                    addChild(child);
                }
            })
        }

        $scope.deleteNode = function () {
            ctrl.myDiagram.model.setDataProperty($scope.selectNode.data, "everExpanded", false);
            ctrl.myDiagram.commandHandler.collapseTree($scope.selectNode);
            // deleteNode($scope.selectNode)
            // ctrl.myDiagram.startTransaction("CollapseExpandTree");
            ctrl.myDiagram.model.removeNodeData($scope.selectNode.data);
            // // ctrl.myDiagram.commitTransaction("CollapseExpandTree");
            // ctrl.myDiagram.zoomToFit();
        }

        $scope.getChildsData = function () {
            var parent = $scope.selectNode.findTreeParentNode();
            var list = [];
            parent.findTreeChildrenNodes().each(function (node) {
                list.push(node.data);
            })
            return list;
        }

        //查询节点
        $scope.search = function () {
            if(!$scope.sltSys.key) {
                $rootScope.toasterWarningInfo("请先选择系统！");
                return false;
            }
            var input = ctrl.search;
            ctrl.myDiagram.startTransaction("highlight search");

            if (input) {
                var regex = new RegExp(input, "i");
                var results = ctrl.myDiagram.findNodesByExample({name: regex});
                ctrl.myDiagram.highlightCollection(results);
                if(!results.first()) {
                    $rootScope.toasterWarningInfo("数据未找到！");
                    return false;
                }
                if(results.first()) {
                    if(results.first().data) {
                        console.log(results.first().data);
                    }
                }
                while(results.iterator.next()) {
                    var newP = ctrl.myDiagram.findNodeForKey(results.key.data.parent_id);
                    findNodeAndExpand(newP);
                }
                if(results.iterator.next() == false) {
                    var newP = ctrl.myDiagram.findNodeForKey(results.first().data.parent_id);
                    findNodeAndExpand(newP);
                }
                if (results.count > 0) ctrl.myDiagram.centerRect(results.first().actualBounds);
            } else {
                ctrl.myDiagram.clearHighlighteds();
                closeNode(1);
            }

            ctrl.myDiagram.commitTransaction("highlight search");
        }

        function findNodeAndExpand(newP) {
            ctrl.myDiagram.model.setDataProperty(newP.data, "everExpanded", true);
            ctrl.myDiagram.commandHandler.expandTree(newP);
            if(newP.data.mapType == "PAGE") {
                var newP = ctrl.myDiagram.findNodeForKey(newP.data.parent_id);
                findNodeAndExpand(newP);
            }
            if(newP.data.level == 2) {
                var newP = ctrl.myDiagram.findNodeForKey(newP.data.parent_id);
                findNodeAndExpand(newP);
            }
            if(newP.data.level == 3) {
                var newP = ctrl.myDiagram.findNodeForKey(newP.data.parent_id);
                findNodeAndExpand(newP);
            }
        }

        // 关闭打开的节点
        function closeNode(level) {
            var crtParentLevelNode = new Array();
            lodash.each(ctrl.mapDatas, function(node) {
                if(!node.level) {
                    if(node.mapType == "PAGE") {
                        crtParentLevelNode.push(node);
                    }
                }
            });
            lodash.each(ctrl.mapDatas, function(node) {
                if(node.level) {
                    if(node.level == 3) {
                        crtParentLevelNode.push(node);
                    }
                }
            });
            lodash.each(ctrl.mapDatas, function(node) {
                if(node.level) {
                    if(node.level == 2) {
                        crtParentLevelNode.push(node);
                    }
                }
            });
            lodash.each(ctrl.mapDatas, function(node) {
                if(node.level) {
                    if(node.level == 1) {
                        crtParentLevelNode.push(node);
                    }
                }
            });
            lodash.each(crtParentLevelNode, function(sltNode) {
                var newP = ctrl.myDiagram.findNodeForKey(sltNode.id);
                ctrl.myDiagram.model.setDataProperty(newP.data, "everExpanded", false);
                ctrl.myDiagram.commandHandler.collapseTree(newP);
            })
        }

        ctrl.myDiagram.addDiagramListener("InitialLayoutCompleted", function (e) {
            e.diagram.findTreeRoots().each(function (r) {
                r.expandTree(2)
            })
        })
        //点击事件

        ctrl.myDiagram.addDiagramListener("ObjectSingleClicked", function (e) {
            $scope.selectNode = e.subject.part;
            ctrl.blur({
                info: e.subject.part.data
            })
        })

        //回车事件
        $scope.enterEvent = function (e) {
            var keycode = window.event ? e.keyCode : e.which;
            if (keycode == 13) {
                $scope.search();
            }
        }

        if (ctrl.diagramScope) {
            ctrl.diagramScope = $scope;
        }
    }
});